﻿using Company.Core.Attributes;
using Company.Core.Helpers;
using Company.Core.Models;
using Company.Logger;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;

namespace Company.Hardware.Camera.Simulation
{
    /// <summary>
    /// 相机仿真子类
    /// </summary>
    [ExposedService(interfaces: typeof(ICamera))]
    public class CameraSimulation : CameraBase
    {
        private AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
        private CameraImage _firstPhoto;

        public override event Action<CameraImage> OnTrigger;

        public override bool DoClose()
        {
            if (Initialized)
            {
                // 关闭相机
                return true;
            }

            return false;
        }

        public override bool DoInitialize()
        {
            // 连接相机
            Thread.Sleep(500);

            // 连接成功后拍一张图
            this.OnTrigger -= InitTakePhoto_OnTrigger;
            this.OnTrigger += InitTakePhoto_OnTrigger;
            _autoResetEvent.Reset();
            if (DoTrigger())
            {
                _autoResetEvent.WaitOne();
                if (_firstPhoto.Width != Config.Width || _firstPhoto.Height != Config.Height)
                {
                    Logs.LogError(new Exception("系统设置中相机尺寸与实际相机分辨率不一致"));
                }

                this.OnTrigger -= InitTakePhoto_OnTrigger;
                return true;
            }

            return false;
        }

        private void InitTakePhoto_OnTrigger(CameraImage obj)
        {
            _firstPhoto = obj;
            _autoResetEvent.Set();
        }

        public override bool DoTrigger()
        {
            Bitmap bitmap = (Bitmap)Image.FromFile(Path.Combine("data", Config.SimulationImage)); // 模拟拍照得到的图像
            var unmanagedArray = new UnmanagedArray2D<ColorBGRA>(Config.Width, Config.Height); // 图像在内存中的表示方式

            // 拿到 Bitmap 的指针
            var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height)
                 , System.Drawing.Imaging.ImageLockMode.ReadWrite
                 , System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            MemoryHelper.CopyMemory(unmanagedArray.IntPtr, bitmapData.Scan0, unmanagedArray.Size);
            bitmap.UnlockBits(bitmapData);

            // 回调
            RaiseTriggerEvent(new CameraImage(unmanagedArray));
            return true;
        }

        private void RaiseTriggerEvent(CameraImage image)
        {
            OnTrigger?.Invoke(image);
        }
    }
}
